import os, string, time
#from stat import ST_MODE, ST_MTIME
#from chmod import chmod
import string
import vcs
import re, regex
from vcs import TEST, TRUE, FALSE, NL, SYSTEM, WINDOWS, UNIX, NULLDEV, SHELL, clr_output
from CCMlog import CCMlog, system, PrintErrorLog
#from YesNoDialog import YesNoDialog
#from etgui import ShowDialog


_LABELS = {}

# Continuuus Environment 

CCM_ADDR = ''
CCM_DELIM = ''

# Begin of Continuus message when an object in Continuus not found 
# We use this message to differentiate 'file not found' state from an error state
gNotFoundObjStr = 'Referenced object version could not be identified:'
gCheckOut_NotFoundObjStr = 'Object version cannot be identified:'


# ----------------------------------------------------
# ---- Continuus custom menu commands ----------------
# ----------------------------------------------------
def CreateProjectDir(absolutePrivateProjectDir):
	# split the project directory path
	splittedProjectDir = string.split(absolutePrivateProjectDir,'/')
	# take only project directtory name (the last part)
	projectDir = splittedProjectDir[-1]
	cmd = "cd %s/..;ccm create /t dir %s"  % (absolutePrivateProjectDir, projectDir)
	rc, out = system(cmd)
	# Oops, something is wrong. Let's see what
	# Continuus returns always 1 when something is wrong
	if rc > 0:
		PrintErrorLog(cmd, rc, out, vcs.err)


# ----------------------------------------------------
# ---- log handling ----------------------------------
# ----------------------------------------------------

_last_rep_file		= ''
_last_log		= None

def log_with_history(use_cache=FALSE):
	global _last_rep_file, _last_log
	if use_cache and _last_rep_file == vcs.repositoryFile:
		if TEST: 
			print "@rReuse log: use_cache = ",use_cache
		#_last_log.reuse()
		return _last_log
	else:
		if string.find(vcs.repositoryFile, ' ') > 0:	# multiple files
			return CCMlog(vcs.repositoryFile)
		if TEST: 
			print "@rMaking new log: use_cache = ",use_cache
			print "repositoryFile = ",vcs.repositoryFile
			print "_last_rep_file = ",_last_rep_file
		_last_log = CCMlog(vcs.repositoryFile)
		#_last_log.close()
		_last_rep_file = vcs.repositoryFile
		if not _last_log:
			_last_rep_file = ''
		return _last_log


# ----------------------------------------------------
# ---- VCS commands ----------------------------------
# ----------------------------------------------------


def IsDifferent():
	# we say it's never different ;-)
	return FALSE


#
#  Change Comment
#
#"$SNIFF_DIR/config/Continuus/sniff_changecomment %w %W/%F '%V' '%C' >&2",
#

def ChangeComment():
		rc, out = system('cd '+ vcs.workingDir + ' ; ccm attr -m comment -v "'+ vcs.comment + ' " ' + vcs.workingFile)
		return rc.test(rc)

#
# Comment
#
# "$SNIFF_DIR/config/Continuus/sniff_comment %w %W/%F '%V'",
#

def Comment():
	log = log_with_history(TRUE)
	if not log:
		return FALSE
	rev = log.revision(vcs.revision)
	if not rev:
		return FALSE
	vcs.output(rev.log_message)
	return TRUE

#
# DeleteVersion
#
# "$SNIFF_DIR/config/Continuus/sniff_deleteversion %w %W/%F '%V' 1>&2",
#

def DeleteVersion():
	return FALSE

################
# Description  #
################
# "$SNIFF_DIR/config/Continuus/sniff_description %w %W/%F",
#

def Description():
	rc,out = system("ccm attr -s sniff_description '"+ vcs.workingDir + "/" + vcs.workingFile + "'")
	vcs.output(out)
	return TRUE

#
#Destructor 
#
# "echo Destructor 1>&2; rm -fr %t",
#

def Destructor():
	return TRUE

#
# DiffText_V_V
# 
# "$SNIFF_DIR/config/Continuus/sniff_difftext_v_v %w %W/%F '%V' '%v'",
#

def DiffText_V_V():
	
	global CCM_DELIM
	if TEST: 
		print "DELIM:" , CCM_DELIM
		print "revision:" , vcs.revision
		print "revision2:" , vcs.revision2
	
	file1=vcs.workingDir + '/' + vcs.workingFile + CCM_DELIM + vcs.revision
	file2=vcs.workingDir + '/' + vcs.workingFile + CCM_DELIM + vcs.revision2
	tmp1=vcs.tmpDir + '/' + vcs.workingFile + CCM_DELIM + vcs.revision
	tmp2=vcs.tmpDir +'/' + vcs.workingFile + CCM_DELIM + vcs.revision2
	system("ccm attr -s source '" + file1 + "' > '" + tmp1 + "'")
	system("ccm attr -s source '" + file2 + "' > '" + tmp2 + "'")
	#file2=
	rc,out = system("diff '" + tmp1 + "' '" + tmp2 + "'")
	vcs.output(out)
	
	return TRUE

#
# DiffText_W_V
#
# "$SNIFF_DIR/config/Continuus/sniff_difftext_w_V %w %W/%F",
#
#

def DiffText_W_V():
	global CMM_DELIM
	if TEST: 
		print "DELIM:" , CCM_DELIM
		print "revision:" , vcs.revision
		print "revision2:" , vcs.revision2
	file=vcs.workingDir + '/' + vcs.workingFile
	rc, prev_version = system("ccm relate -s -n successor -to '"+ file + "'")
	prev_version=string.split(prev_version,' ')
	prev_version=prev_version[0]
	tmp1=vcs.tmpDir + '/' + vcs.workingFile
	system("ccm attr -s source  '" + prev_version + "' > '" + tmp1 + "'")
	rc,out = system("diff '" + file + "' '" + tmp1 + "'")
	vcs.output(out)
	
	return TRUE

#
# RevisionOfSymbol
#
# "$SNIFF_DIR/config/Continuus/printargs RevisionOfSymbol >&2",
#

def RevisionOfSymbol():
	return FALSE

#
# SetDescription
# 
#"$SNIFF_DIR/config/Continuus/sniff_setdescription %w %W/%F '%I' 1>&2",
#
#

def SetDescription():
	rc, out = system("ccm attr -d sniff_description '" + vcs.workingDir + '/' + vcs.workingFile + "'")
	rc, out = system("ccm attr -c sniff_description -t string -v '" + vcs.description + "'  '"  + vcs.workingDir + '/' + vcs.workingFile + "'")
	return vcs.test(rc)

#
# SymbolList
#
# "$SNIFF_DIR/config/Continuus/sniff_symbollist %W '%F'",
#

def SymbolList():
	if TEST: print "@r SymbolList():"
	log = log_with_history(FALSE)
	if not log:
		return FALSE
	out_list = []
	while log:
		out_list.append('\014%s' % log.work_file())
		out_list.append('HEAD: %s' % log.head_rev())
		symbols = log.symbolstr()
		if symbols:
			out_list.append(symbols)
		for rev in log.revision_list():
			theText = rev.ccmrev + " " + rev.rev + " " + rev.date + "; " + rev.author + "; " # + rev.lines +  ";"
			out_list.append(theText)
		if log.is_last_file():
			break
		else:
			log.next()
	theOutput = string.join(out_list, NL)
	if TEST: print theOutput
	vcs.output(theOutput)
	return TRUE


#
# Unlock
#
# "$SNIFF_DIR/config/Continuus/sniff_deleteversion %w %W/%F '%V'  1>&2",
#

def Unlock():
	return TRUE



#
#  
# ehemaliger Aufruf:
#  "$SNIFF_DIR/config/Continuus/sniff_ccm_command %w 'ccm co %W/%F 1>&2'",
#  

def CheckOut():
	if TEST : print 'vcs.lockType', vcs.lockType
	if vcs.lockType == 'N' : return TRUE
	if TEST : print 'after if vcs.lockType', vcs.lockType
	args = (vcs.workingDir,vcs.workingFile)
	cmd = "ccm co '%s/%s'" % args
	rc, out = system(cmd)

	if rc > 0:
		# if object not found in Continuus, then print this message
		if regex.match(gCheckOut_NotFoundObjStr, out) == len(gCheckOut_NotFoundObjStr) :
			print "File not under Continuus control"
		else:
			PrintErrorLog(cmd, rc, out, vcs.err)

	return vcs.test(rc)
# 

#
# ehemaliger Aufruf:
# "$SNIFF_DIR/config/Continuus/sniff_checkin %w %W/%F '%C' '%S' %L 1>&2'",
#


def CheckIn():
	args = (vcs.comment,vcs.workingDir,vcs.workingFile)
	cmd = "ccm ci -c '%s' '%s/%s' " % args
	rc, out = system(cmd)

	if rc > 0:
		# if object not found in Continuus, then create it
		if regex.match(gNotFoundObjStr, out) == len(gNotFoundObjStr) :
			print "File not under Continuus control, creating ...."
			cmd = "ccm create -c '%s' '%s/%s' " % args
			rc, out = system(cmd)

			if rc > 0:
				PrintErrorLog(cmd, rc, out, vcs.err)
			else:
				args = (vcs.workingDir,vcs.workingFile)
				cmd = "ccm ci -nc '%s/%s' " % args
				rc, out = system(cmd)
				if rc > 0:
					PrintErrorLog(cmd, rc, out, vcs.err)
		
	return vcs.test(rc)

# 
# vcs.is_reachable testet auf executables im PATH
# hier also testen ob ccm aufrufbar ist !
#  

def Constructor():
	if not os.path.isdir(vcs.tmpDir):
		vcs.mkdir_p(vcs.tmpDir)
	return TRUE

def TestTool():
	global CCM_ADDR , CCM_DELIM
	if TEST : print 'Continuus Adapter TestTool:'
	if vcs.is_reachable('ccm'):
		#CCM_ADDR = system('ccm status | grep "(current session)"  |  cut -f4 -d " "')
		rc, CCM_ADDR = system("ccm status | grep '(current session)'  |  cut -f4 -d ' '")
		CCM_ADDR = string.split(CCM_ADDR,NL)
		CCM_ADDR = CCM_ADDR[0]
		if CCM_ADDR == '':
			vcs.output('No running Continuus Session found, is Continuus startet or is PATH not correct ?')
			return FALSE
		rc, CCM_DELIM = system('ccm delim')
		CCM_DELIM = string.split(CCM_DELIM)
		CCM_DELIM = CCM_DELIM[0]
		CCM_DELIM = string.strip(CCM_DELIM)
		return TRUE
	vcs.output('ccm Executable not found, maintain Path Environment')
	return FALSE



def RepositoryDir():
	#RCS has:
	#vcs.output(vcs.joinpath(vcs.RCCSPath, vcs.catDir, 'RCS'))
	vcs.output(vcs.workingDir)
	return TRUE



def CheckRepositoryDir():
	return TRUE


def CheckRepositoryFile():
	return TRUE



def CreateRepositoryFile():
	return TRUE



def DateOfRepositoryFile():
	# since we cannot know when RepFile was changed,
	curTime = time.time()
	outString = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(curTime))
	vcs.output(outString)
	return TRUE



_LockerCache = {}
def GetLocker(dirName, fileName):
	global _LockerCache
	curTime = time.time()
	try:
		(cachedTime, lockerList) = _LockerCache[dirName]
		# Variant 1: use a fixed time how long cache is valid (e.g. 20 sec.)
		#if cachedTime - curTime > 20:
		#	lockerList = None
		# Variant 2: cache is valid until local file is modified
		theStat = vcs.stat(vcs.joinpath(dirName, fileName))
		modTime = theStat.get_mtime()
		if modTime > cachedTime:
			# file has been modified since last lockers call! Invalidate Cache.
			lockerList = None
	except:
		lockerList = None
	if not lockerList:
		rc, lockerString = system("CCM Controled")
		if not lockerString:
			print "Error"
			cachedLockers = {}
		else:
			# process the lockers and enter into the cache
			lockerList = processLockers(lockerString)
			_LockerCache[dirName] = (curTime, lockerList)
	# Assert (now, cachedLockers is valid)
	try:
		theLocker = lockerList[fileName]
	except:
		# filename is not in the lockerlist
		theLocker = ""
	return theLocker


def processLockers(String):

	return String



def Lockers():

	if TEST :
		print "working dir: "+vcs.workingDir
		print "working File: "+vcs.workingFile

	rc,out = system("cd "+vcs.workingDir+" ; ccm ls -f '%name %owner: %version' '"+vcs.workingFile+"'")
	if out[:10] == "Referenced":
		
		out=vcs.workingFile+" No_CCM_Control:"
		
	out=string.split(out,NL)
	out=out[0]
	vcs.output(out)
	return TRUE
	
	
	
def Lock():
	return TRUE



def HistoryOfRevision():
#    args = (vcs.privateRoot,vcs.workingDir,vcs.workingFile,vcs.revision)
#    out= system ("$SNIFF_DIR/config/Continuus/sniff_historyofrevision %s %s/%s '%s'" % args)
#    print 'Historie vorher: %s' % out
#    vcs.output(out)
#    print 'Historie nacher: '
	log = log_with_history(TRUE)
	if not log:
		return FALSE
	rev = log.revision(vcs.revision)
	if not rev:
		return FALSE
	vcs.output(str(rev))
	return TRUE



def History():
	#if TEST: print "@r Hisotry() begin:"
	log = log_with_history(TRUE)
	if not log:
		return FALSE
	vcs.output(log.history_str())
	#if TEST: print "@r History() end:"
	return TRUE



def UpdateFile():
	rc,out = system('cd ' + vcs.workingDir + ' ; ccm use -r '+vcs.workingFile)
	return TRUE


if __name__ == "__main__":
	pass
